home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / drivers1.zip / ISOLAN.ASM < prev    next >
Assembly Source File  |  1992-01-23  |  14KB  |  652 lines

  1. version    equ    2
  2.  
  3.     include    defs.asm    ;SEE ENCLOSED COPYRIGHT MESSAGE
  4.  
  5. ; Packet driver for BICC Data Networks' ISOLAN 4110 ethernet
  6. ; controller, written by
  7. ;    Rainer Toebbicke
  8. ;    European Organisation of Nuclear Research (CERN)
  9. ;    Geneva, Switzerland
  10. ; based on the "generic" packet driver by Russell Nelson.
  11.  
  12.  
  13.  
  14. ; BICC ISOLAN card constants
  15.  
  16. IS_SAP    struc            ;Service Access Point channel
  17. IS_S_Data    db    ?    ;data semaphore
  18. IS_S_Taken    db    ?    ;taken semaphore
  19.         dw    ?
  20.  
  21. IS_S_Event    db    ?
  22.  
  23. IS_S_SrcEaddr    db    6 dup(?)    ;source Ethernet address
  24. IS_S_SrcLsap    db    ?
  25. IS_S_DstEaddr    db    6 dup(?)
  26. IS_S_DstLsap    db    ?
  27.         db    ?
  28. IS_S_Status    dw    ?
  29.         db    ?
  30. IS_S_SDUptr    dw    ?
  31. IS_SAP        ends
  32.  
  33. ; Bits defined in IS_S_Event
  34. IS_M_Init    equ    0ch
  35. IS_M_DataRq    equ    09h
  36. IS_M_DataInd    equ    0ah
  37. IS_Board_Init    equ    0dh
  38.  
  39.  
  40. IS        segment    at 0
  41.         org    8000h
  42. IS_Sign        db    ?        ;test for card presence
  43. IS_Reset    db    ?
  44. IS_Diagok    db    ?
  45. IS_Error    db    ?
  46. IS_ErrCode    db    ?
  47.         org    800eh
  48. IS_PgmStart    dw    ?
  49.  
  50. IS_IER        db    ?        ;interrupt enable register
  51. IS_I_Tx        equ    01h        ;transmit interrupt
  52. IS_I_Rx        equ    02h        ;receive interrupt
  53.  
  54. IS_ISR        db    ?        ;interrupt status reg
  55.         org    8014h
  56. IS_BlueBook    db    ?
  57. IS_LLC1        db    ?
  58. IS_Precv    db    ?        ;promiscuous receive flag
  59. IS_LanceRev    db    ?
  60. IS_MacReflSup    db    ?        ;MAC reflection suppression
  61.         org    8020h
  62. IS_Xmit        IS_SAP    <>        ;Transmit channel
  63.         org    8040h
  64. IS_Rcv        IS_SAP    <>        ;Receive channel
  65.         org    8060h
  66. IS_Eaddr    db    6 dup(?)    ;This card's Ethernet address
  67.  
  68. IS        ends
  69.  
  70.  
  71. IS_SDU        struc
  72. IS_SDU_DataOff    db    ?        ;offset to data
  73. IS_SDU_L    dw    ?        ;length of packet
  74. IS_SDU        ends
  75.  
  76.  
  77. ENET_HDR    equ    EADDR_LEN*2+2    ;length of ethernet header
  78.  
  79.  
  80.  
  81. code    segment    word public
  82.     assume    cs:code, ds:code
  83.  
  84.     public    int_no,    MemBase
  85. int_no    db    2,0,0,0            ;must be four bytes long for get_number.
  86. MemBase    dw    0b800h,0
  87.  
  88.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  89. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  90. driver_type    db    4+128        ;from the packet spec
  91. driver_name    db    'ISOLAN',0    ;name of the driver.
  92. driver_function    db    2
  93. parameter_list    label    byte
  94.     db    1    ;major rev of packet driver
  95.     db    9    ;minor rev of packet driver
  96.     db    14    ;length of parameter list
  97.     db    EADDR_LEN    ;length of MAC-layer address
  98.     dw    GIANT    ;MTU, including MAC headers
  99.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  100.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  101.     dw    0    ;(# of successive xmits) - 1
  102. int_num    dw    0    ;Interrupt # to hook for post-EOI
  103.             ;processing, 0 == none,
  104.  
  105.     public    rcv_modes
  106. rcv_modes    dw    4        ;number of receive modes in our table.
  107.         dw    0,0,0,rcv_mode_3
  108.  
  109.     include    movemem.asm
  110.     include    timeout.asm
  111.  
  112.     public    as_send_pkt
  113. ; The Asynchronous Transmit Packet routine.
  114. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  115. ;   interrupts possibly enabled.
  116. ; Exit with nc if ok, or else cy if error, dh set to error number.
  117. ;   es:di and interrupt enable flag preserved on exit.
  118. as_send_pkt:
  119.     ret
  120.  
  121.     public    drop_pkt
  122. ; Drop a packet from the queue.
  123. ; Enter with es:di -> iocb.
  124. drop_pkt:
  125.     assume    ds:nothing
  126.     ret
  127.  
  128.     public    xmit
  129. ; Process a transmit interrupt with the least possible latency to achieve
  130. ;   back-to-back packet transmissions.
  131. ; May only use ax and dx.
  132. xmit:
  133.     assume    ds:nothing
  134.     ret
  135.  
  136.  
  137.     public    send_pkt
  138. send_pkt:
  139. ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
  140. ;  (only if the high-performance bit is set in driver_function)
  141. ;enter with ds:si -> packet, cx = packet length.
  142. ;exit with nc if ok, or else cy if error, dh set to error number.
  143.     assume    ds:nothing
  144.  
  145.     cld                ;moves go forward
  146.     mov    ax,MemBase
  147.     mov    es,ax            ;address the card
  148.     assume    es:IS
  149.     push    cx            ;save length
  150.  
  151. ; Wait for the transmit channel to become free
  152.     mov    cx,10            ;wait 10 36ths of a second.
  153.     call    set_timeout
  154. tx_wait:
  155.     test    IS_Xmit.IS_S_Data,0ffh
  156.     jnz    tx_idle
  157.     call    do_timeout
  158.     jnz    tx_wait
  159.     pop    cx            ;remove from stack
  160.     mov    dh,CANT_SEND        ;transmit error
  161.     stc
  162.     ret
  163.  
  164. tx_idle:
  165.     mov    IS_Xmit.IS_S_Data,0        ;our channel now
  166.     mov    IS_Xmit.IS_S_Event,IS_M_DataRq    ;sending Data
  167.  
  168. ; copy destination ethernet addr
  169.     mov    cx,EADDR_LEN/2
  170.     lea    di,IS_Xmit.IS_S_DstEaddr
  171.     rep    movsw
  172.  
  173. ; copy source ethernet addr
  174.     mov    cx,EADDR_LEN/2
  175.     lea    di,IS_Xmit.IS_S_SrcEaddr
  176.     rep    movsw
  177.  
  178. ; copy type field
  179.     lodsw
  180.     xchg    ah,al                ;8086 order
  181.     mov    IS_Xmit.IS_S_Status,ax
  182.  
  183.     pop    cx                ;restore count
  184.     sub    cx,ENET_HDR            ;minus header
  185.  
  186.     mov    di,IS_Xmit.IS_S_SDUptr        ;point to SDU
  187.     mov    es:IS_SDU_L[di],cx        ;set count
  188.     xor    ah,ah
  189.     mov    al,es:IS_SDU_DataOff[di]
  190.     add    di,ax                ;point to data
  191.  
  192.     call    movemem                ; now copy the buffer
  193.  
  194.     mov    IS_Xmit.IS_S_Taken,1        ;release channel
  195.     clc                    ;no error occurred
  196.     ret
  197.     assume    es:nothing
  198.  
  199.  
  200.     public    get_address
  201. get_address:
  202. ;get the address of the interface.
  203. ;enter with es:di -> place to get the address, cx = size of address buffer.
  204. ;exit with nc, cx = actual size of address, or cy if buffer not big enough.
  205.     assume    ds:code
  206.     cmp    cx,EADDR_LEN
  207.     jnb    get_addr_ok        ;buffer ok
  208.     stc
  209.     ret
  210.  
  211. get_addr_ok:
  212.     push    ds
  213.     push    si
  214.     mov    ax,MemBase        ;point to interface
  215.     mov    ds,ax
  216.     assume    ds:IS
  217.  
  218.     mov    si,offset IS_Eaddr    ;point to our E-net addr
  219.     mov    cx,EADDR_LEN/2
  220.     rep    movsw
  221.     pop    si
  222.     pop    ds
  223.     mov    cl,EADDR_LEN
  224.     clc
  225.     ret
  226.  
  227.  
  228.  
  229.     public    set_address
  230. set_address:
  231. ;enter with ds:si -> Ethernet address, CX = length of address.
  232. ;exit with nc if okay, or cy, dh=error if any errors.
  233.     assume    ds:nothing
  234.     cmp    cx,EADDR_LEN
  235.     jnb    set_addr_ok        ;buffer ok
  236.     mov    dh,BAD_ADDRESS
  237.     stc
  238.     ret
  239.  
  240. set_addr_ok:
  241.     push    es
  242.     push    di
  243.     mov    ax,MemBase        ;point to interface
  244.     mov    es,ax
  245.     assume    es:IS
  246.  
  247.     mov    di,offset IS_Eaddr    ;point to our E-net addr
  248.     mov    cx,EADDR_LEN/2
  249.     rep    movsw
  250.  
  251. ; reset the board's software, don't really know if this is needed
  252.     mov    IS_Xmit.IS_S_Data,0        ;our channel now
  253.     mov    IS_Xmit.IS_S_Event,IS_Board_Init ;reboot
  254.     mov    IS_Xmit.IS_S_Taken,1        ;issue the command
  255.  
  256. ; wait for request to complete
  257.     mov    cx,10            ;wait 10 36ths of a second.
  258.     call    set_timeout
  259. set_wait_2:
  260.     test    IS_Xmit.IS_S_Data,0ffh
  261.     jnz    set_done
  262.     call    do_timeout
  263.     jnz    set_wait_2
  264.  
  265. set_done:
  266.     mov    cx,EADDR_LEN        ;return their address length.
  267.     pop    di
  268.     pop    es
  269.     assume    es:nothing
  270.     clc
  271.     ret
  272.  
  273.  
  274.  
  275. rcv_mode_3:
  276. ;receive mode 3 is the only one we support, so we don't have to do anything.
  277.     ret
  278.  
  279.  
  280.     public    set_multicast_list
  281. set_multicast_list:
  282. ;enter with ds:si ->list of multicast addresses, cx = number of addresses.
  283. ;return nc if we set all of them, or cy,dh=error if we didn't.
  284.     mov    dh,NO_MULTICAST
  285.     stc
  286.     ret
  287.  
  288.  
  289.     public    terminate
  290. terminate:
  291.     ret
  292.  
  293.     public    reset_interface
  294. reset_interface:
  295. ;reset the interface.
  296.     assume    ds:code
  297.     push    ds
  298.     mov    ax,MemBase
  299.     mov    ds,ax
  300.     assume    ds:IS
  301.     mov    IS_IER,0
  302.     pop    ds
  303.     ret
  304.  
  305.  
  306. ;called when we want to determine what to do with a received packet.
  307. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  308.     extrn    recv_find: near
  309.  
  310. ;called after we have copied the packet into the buffer.
  311. ;enter with ds:si ->the packet, cx = length of the packet.
  312.     extrn    recv_copy: near
  313.  
  314.     extrn    count_in_err: near
  315.     extrn    count_out_err: near
  316.  
  317.     public    recv
  318. recv:
  319. ;called from the recv isr.  All registers have been saved, and ds=cs.
  320. ;Upon exit, the interrupt will be acknowledged.
  321.     assume    ds:code
  322.     mov    ax,MemBase
  323.     mov    ds,ax
  324.     assume    ds:IS
  325.  
  326.     mov    al,IS_ISR        ;get interrupt status
  327.     test    al,IS_I_RX        ;receive interrupt?
  328.     jnz    rcv_test_errors        ;yes...
  329.     jmp    rcv_done
  330.  
  331. rcv_test_errors:
  332.  
  333. ; some thorough testing missing here
  334. ; anyway, don't know what to test
  335.  
  336.  
  337. rcv_no_errors:
  338.     mov    IS_Rcv.IS_S_Data,0    ;block channel
  339.     mov    di,IS_Rcv.IS_S_SDUptr    ;point to SDU
  340.     mov    cx,IS_SDU_L[di]        ;get length
  341.     add    cx,ENET_HDR        ;plus ethernet header
  342.  
  343.  
  344. ; These following lines correctly point to the type field.
  345. ; Addressability to the whole buffer on the 'receiver' call
  346. ; would be lost, a feature useful to some applications
  347.  
  348. ;    mov     ax,IS_Rcv.IS_S_Status ;get type field
  349. ;    xchg    ah,al         ;in network byte order
  350. ;    push    ax         ;have to place it somewhere
  351. ;    mov    di,sp
  352. ;    push    ss
  353. ;    pop    es            ;es:di at type field
  354.  
  355. ; The following 'hack' keeps addressability to the packet
  356. ; on the 'receiver' call but stays compatible with the
  357. ; packet driver skeleton.
  358. ; This feature is indicated by a bit in the type number (ugly)
  359. ; which the application can examine
  360.  
  361.     mov    al,IS_SDU_DataOff[di]    ;offset to to data
  362.     sub    al,2            ;offset to type field
  363.     cbw
  364.     add    di,ax            ;point to type field
  365.     push    ds
  366.     pop    es            ;es:di->type field
  367.  
  368.     push    cs
  369.     pop    ds            ;don't confuse recv_find
  370.     assume    ds:code
  371.  
  372.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  373.     mov    ax, es:[di]
  374.     xchg    ah, al
  375.     cmp     ax, 1500
  376.     ja    BlueBookPacket
  377.     inc    di            ;set di to 802.2 header
  378.     inc    di
  379.     mov    dl, IEEE8023
  380. BlueBookPacket:
  381.     call    recv_find        ;do we want this packet?
  382. ;    add    sp,2               ;remove type field
  383.  
  384.     mov    ax,es
  385.     or    ax,di
  386.     jz    rcv_done_0        ;pointer zero, give up
  387.  
  388.     push    es
  389.     push    di            ;save pointer
  390.  
  391.     mov    ax,MemBase
  392.     mov    ds,ax
  393.     assume    ds:IS
  394.  
  395. ; set up ethernet header
  396.     mov    cx,EADDR_LEN/2
  397.     mov    si,offset IS_Rcv.IS_S_DstEaddr
  398.     rep    movsw
  399.     mov    cx,EADDR_LEN/2
  400.     mov    si,offset IS_Rcv.IS_S_SrcEaddr
  401.     rep    movsw
  402.     mov    ax,IS_Rcv.IS_S_Status        ;type field
  403.     xchg    ah,al                ;in network byte order
  404.     stosw
  405.  
  406.     mov    si,IS_Rcv.IS_S_SDUptr        ;point to SDU
  407.     mov    cx,IS_SDU_L[si]            ;get length
  408.     push    cx                ;save for later
  409.     mov    al,IS_SDU_DataOff[si]
  410.     xor    ah,ah
  411.     add    si,ax                ;point to data
  412.  
  413.     call    movemem
  414.  
  415.     pop    cx            ;restore count
  416.     pop    si            ;restore pointer
  417.     pop    ds            ;restore pointer
  418.     assume    ds:nothing
  419.  
  420.     add    cx,ENET_HDR        ;adjust length
  421.     call    recv_copy        ;wake up client
  422.  
  423. rcv_done_0:
  424.     mov    ax,MemBase        ;point to interface
  425.     mov    ds,ax
  426.     assume    ds:IS
  427.  
  428. rcv_done:
  429.     mov    IS_Rcv.IS_S_Taken,1    ;release channel
  430.     mov    IS_ISR,0        ;clear interrupt
  431.     push    cs
  432.     pop    ds
  433.     assume    ds:code
  434.     ret
  435.  
  436.  
  437.     public    recv_exiting
  438. recv_exiting:
  439. ;called from the recv isr after interrupts have been acknowledged.
  440. ;Only ds and ax have been saved.
  441.     assume    ds:nothing
  442.     ret
  443.  
  444.  
  445. ;any code after this will not be kept after initialization.
  446. end_resident    label    byte
  447.  
  448.  
  449.     public    usage_msg
  450. usage_msg db "usage: ISOLAN [-n] [-d] [-w] <packet_int_no> <int_level>    <mem_addr>",CR,LF,'$'
  451.  
  452.     public    copyright_msg
  453. copyright_msg    db    "Packet    driver for BICC    ISOLAN device, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF
  454.         db    "Portions Copyright 1989, R.Toebbicke, CERN, Switzerland",CR,LF
  455.         db    '$'
  456.  
  457. errmsg1    db    "No BICC Isolan    board found at this address.",CR,LF,'$'
  458. diag_errmsg    db    "Error - ISOLAN    Diagnostics failed.",CR,LF,'$'
  459.  
  460. diag_start_msg    db    "ISOLAN    Diagnostics running... $"
  461. diag_end_msg    db    " done.",CR,LF,'$'
  462.  
  463. int_no_name    db    "Interrupt number $"
  464. MemBaseName    db    "Shared    Memory address $"
  465. MemPrt    dw    0c000h,0
  466.  
  467.  
  468.  
  469.     extrn    set_recv_isr: near
  470.  
  471. ;enter with si -> argument string, di -> word to store.
  472. ;if there is no number, don't change the number.
  473.     extrn    get_number: near
  474.  
  475. ;enter with dx -> name of word, di -> dword to print.
  476.     extrn    print_number: near
  477.  
  478.     public    parse_args
  479. parse_args:
  480. ;exit with nc if all went well, cy otherwise.
  481.     mov    di,offset int_no
  482.     call    get_number
  483.     mov    di,offset MemPrt
  484.     call    get_number
  485.     mov    di,MemPrt
  486.     sub    di,800h            ;BICC standard notation
  487.     mov    MemBase,di
  488.     clc
  489.     ret
  490.  
  491.  
  492. bad_board:
  493.     mov    dx,offset errmsg1
  494. err_msg:
  495.     assume    ds:nothing
  496.     push    cs
  497.     pop    ds
  498.     mov    ah,9
  499.     int    21h
  500.     stc
  501.     ret
  502.  
  503.  
  504.     public    etopen
  505. etopen:
  506.     mov    ax,MemBase
  507.     mov    ds,ax
  508.     assume    ds:IS
  509.  
  510. ; test if board exists
  511.     mov    IS_Sign,42
  512.     cmp    IS_Sign,42
  513.     jne    bad_board
  514.  
  515.     mov    IS_Sign,0ffh-42
  516.     cmp    IS_Sign,0ffh-42
  517.     jne    bad_board
  518.  
  519.     cmp    IS_Reset,01h        ;already running?
  520.     jne    diag_not_ok
  521.     jmp    diag_ok            ;yes, let it run
  522. diag_not_ok:
  523.  
  524.     mov    IS_Reset,0
  525.     mov    cx,10            ;wait 10 36ths of a second.
  526.     call    set_timeout
  527. diag_w_0:
  528.     cmp    IS_Reset,0fah
  529.     je    diag_1
  530.     call    do_timeout
  531.     jne    diag_w_0
  532.  
  533. diag_1:
  534.     mov    IS_Reset,0ffh
  535.     mov    cx,10            ;wait 10 36ths of a second.
  536.     call    set_timeout
  537. diag_w_1:
  538.     cmp    IS_Reset,0fah
  539.     je    diag_2
  540.     call    do_timeout
  541.     jne    diag_w_1
  542.  
  543. diag_2:
  544.     mov    IS_Reset,0e5h
  545.     mov    cx,10            ;wait 10 36ths of a second.
  546.     call    set_timeout
  547. diag_w_2:
  548.     cmp    IS_Reset,0fah
  549.     je    diag_3
  550.     call    do_timeout
  551.     jne    diag_w_2
  552.  
  553. diag_3:
  554.     mov    IS_Reset,09dh        ;start diagnostics
  555.  
  556.     push    ds
  557.     push    cs
  558.     pop    ds
  559.     mov    dx,offset diag_start_msg
  560.     mov    ah,9
  561.     int    21h
  562.     pop    ds
  563.  
  564.     mov    bx,72            ;double loop, takes some time
  565. diag_w_3_0:
  566.     mov    cx,10            ;wait 10 36ths of a second.
  567.     call    set_timeout
  568. diag_w_3:
  569.     cmp    IS_Diagok,01h
  570.     je    diag_4
  571.     call    do_timeout
  572.     jne    diag_w_3
  573.     dec    bx
  574.     jnz    diag_w_3_0
  575.     mov    dx,offset diag_errmsg
  576.  
  577. diag_4:
  578.     push    ds
  579.     push    cs
  580.     pop    ds
  581.     mov    dx,offset diag_end_msg
  582.     mov    ah,9
  583.     int    21h
  584.     pop    ds
  585.  
  586.     mov    ax,0800h
  587.     mov    IS_PgmStart,ax
  588.     mov    IS_Reset,01h        ;run the program
  589.  
  590.  
  591. ; enable the board's interrupts
  592. diag_ok:
  593.     push    ds
  594.     push    cs
  595.     pop    ds            ;set cs=ds
  596.     call    set_recv_isr
  597.     pop    ds
  598.  
  599.     mov    IS_BlueBook,1        ;enable Blue Book MAC
  600.     mov    IS_LLC1,1        ;disable LLC1 service
  601.     mov    IS_MacReflSup,1        ;suppress MAC reflection
  602.     mov    IS_IER,IS_I_RX        ;enable for receive
  603.     mov    IS_ISR,0        ;clear previous
  604.  
  605. ; reset the board's software, just in case...
  606.     mov    IS_Xmit.IS_S_Data,0        ;our channel now
  607.     mov    IS_Xmit.IS_S_Event,IS_Board_Init ;init MAC layer
  608.     mov    IS_Xmit.IS_S_Taken,1        ;issue the command
  609.  
  610. ; again wait for request to complete
  611.     mov    cx,10            ;wait 10 36ths of a second.
  612.     call    set_timeout
  613. in_wait_2:
  614.     test    IS_Xmit.IS_S_Data,0ffh
  615.     jnz    in_done
  616.     call    do_timeout
  617.     jne    in_wait_2
  618.  
  619. in_done:
  620.  
  621.     mov    al, int_no        ; Get board's interrupt vector
  622.     add    al, 8
  623.     cmp    al, 8+8            ; Is it a slave 8259 interrupt?
  624.     jb    set_int_num        ; No.
  625.     add    al, 70h - 8 - 8        ; Map it to the real interrupt.
  626. set_int_num:
  627.     xor    ah, ah            ; Clear high byte
  628.     mov    int_num, ax        ; Set parameter_list int num.
  629.  
  630. ;if all is okay,
  631.     mov    dx,offset end_resident
  632.     push    cs
  633.     pop    ds
  634.     clc
  635.     ret
  636.  
  637.     public    print_parameters
  638. print_parameters:
  639. ;echo our command-line parameters
  640.     mov    di,offset int_no
  641.     mov    dx,offset int_no_name
  642.     call    print_number
  643.     mov    di,offset MemPrt
  644.     mov    dx,offset MemBaseName
  645.     call    print_number
  646.     ret
  647.  
  648.  
  649. code    ends
  650.  
  651.     end
  652.